﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Audio;
using System;
using WindowsGame1;

class Ball : BallBase, IBall
{
    public SpriteFont PausedFont;
    Player[] Platforms = new Player[4];
    int lastHit = 5;
    public int numPlayers;
    SpriteBatch spriteBatch;
    Texture2D particleBase;
    SoundEffect DeadSound;
    SoundEffect BounceSound;
    float ballRadius = 0.01875f;
    int Scale;
    public float Aspect;
    public Vector2 Position;
    public Vector2 Direction;
    public bool Paused;
    float ResumeInSec;
    int aquiredSpeed = 0;
    ParticleSystem particleSystem;
    Random random;

    public void Pause()
    {
        Paused = true;
        ResumeInSec = 1;
    }

    public Ball(SpriteBatch spriteBatch, Texture2D particleBase, Vector2 WindowSize, Player[] Paddles, SoundEffect sound, SoundEffect sound2)

    {
        this.DeadSound = sound;
        this.BounceSound = sound2;
        for (int i = 0; i < Paddles.Length; i++)
        {
            this.Platforms[i] = Paddles[i];
        }
        this.spriteBatch = spriteBatch;
        this.particleBase = particleBase;
        this.Scale = (int)WindowSize.Y;
        random = new Random();
        particleSystem = new ParticleSystem(Position);
        particleSystem.AddEmitter(new Vector2(0.001f, 0.0015f),
                                    new Vector2(0, -1),
                                    new Vector2((float)(-0.128f * Math.PI*8), (float)(0.128f * Math.PI*8)),
                                    new Vector2(0.75f, 1.0f),
                                    new Vector2(0.025f, 0.0375f),
                                    new Vector2(0.0125f, 0.0180f),
                                    Color.White, Color.Black, Color.Orange, Color.Orange,
                                    new Vector2(0.00f, 0.27f),
                                    new Vector2(0.00f, 0.04f),
                                    1000, Vector2.Zero, particleBase);
        particleSystem.AddEmitter(new Vector2(0.001f, 0.0015f),
                                    new Vector2(0, -1),
                                    new Vector2((float)(-0.128f * Math.PI * 8), (float)(0.128f * Math.PI * 8)),
                                    new Vector2(0.75f, 1.0f),
                                    new Vector2(0.025f, 0.0375f),
                                    new Vector2(0.0125f, 0.0180f),
                                    Color.White, Color.Black, Color.Orange, Color.Orange,
                                    new Vector2(0.00f, 0.02f),
                                    new Vector2(0.00f, 0.00f),
                                    1000, Vector2.Zero, particleBase);
        
    }

    public void ReInitialize()
    {
        Position = new Vector2(0.5f*this.Aspect, 0.5f);
        particleSystem.Position = Position;
        particleSystem.LastPos = Position;
        Direction = new Vector2((float)random.NextDouble() - 0.5f, (float)(random.NextDouble() - 0.5f)/1.5f);
        Direction.Normalize();
        if (Math.Abs(Direction.Y) > Math.Abs(Direction.X))
        {
            Direction.Y = Direction.X;
        }
        Direction.Normalize();
        aquiredSpeed = aquiredSpeed / 2;
        Direction *= 0.5f * (float)Math.Pow(1.05, aquiredSpeed);
        lastHit = 5;
        particleSystem.Clear();
        ResetBallParticleSystem(Direction.Length());
    }

    public void Restart(int lives)
    {
        for (int i = 0; i < numPlayers; i++)
        {
            Platforms[i].Reset(lives);
        }
        ReInitialize();
        Paused = false;
    }

    public void Update(float dt)
    {
        if (!Paused)
        {
            Rectangle ballRect = new Rectangle((int)((Position.X - ballRadius) * Scale), (int)((Position.Y - ballRadius) * Scale), (int)(ballRadius * 2 * Scale), (int)(ballRadius * 2 * Scale));
            int i = 0;
            for (i = 0; i < numPlayers; i++)
            {
                if (ballRect.Intersects(new Rectangle((int)(Platforms[i].Position.X * Scale), (int)(Platforms[i].Position.Y * Scale), (int)(Platforms[i].Size.X * Scale), (int)(Platforms[i].Size.Y * Scale))))
                {
                    if (i == 0 || i == 1)
                    {
                        if (lastHit != i)
                        {
                            float speed = Direction.Length() * 1.1f;
                            aquiredSpeed++;
                            Direction.Normalize();
                            float distFromMiddle = (Platforms[i].Position.Y + Platforms[i].Size.Y / 2 - Position.Y) / Platforms[i].Size.Y;    // Negative is below, positive is above [-1, 1]
                            // The most rear adds 2 
                            BounceSound.Play();
                            Direction.Y += -2 * distFromMiddle;
                            Direction.X *= -1;
                            Direction.Normalize();
                            speed = MathHelper.Clamp(speed, 0, 3);
                            Direction *= speed;
                            lastHit = i;
                            #region ChangeBallParticleSystem
                            particleSystem.EmitterList[0].StartColor1 = Platforms[i].particleSystem.EmitterList[0].StartColor1;
                            particleSystem.EmitterList[0].StartColor2 = Platforms[i].particleSystem.EmitterList[0].StartColor2;
                            particleSystem.EmitterList[0].EndColor1 = Platforms[i].particleSystem.EmitterList[0].EndColor1;
                            particleSystem.EmitterList[0].EndColor2 = Platforms[i].particleSystem.EmitterList[0].EndColor2;
                            particleSystem.EmitterList[1].StartColor1 = Platforms[i].particleSystem.EmitterList[0].StartColor1;
                            particleSystem.EmitterList[1].StartColor2 = Platforms[i].particleSystem.EmitterList[0].StartColor2;
                            particleSystem.EmitterList[1].EndColor1 = Platforms[i].particleSystem.EmitterList[0].EndColor1;
                            particleSystem.EmitterList[1].EndColor2 = Platforms[i].particleSystem.EmitterList[0].EndColor2;
                            SetBallParticleSystem(speed);
                            #endregion
                        }
                    }
                }
            }
            if (numPlayers < 4)
            {
                if (Position.Y < ballRadius || Position.Y > 1.0f - ballRadius)
                {
                    Direction.Y *= -1;
                    BounceSound.Play();
                }
                else if (Position.X + ballRadius < 0)
                {
                    Platforms[0].ReduceLife();
                    Pause();
                    this.ReInitialize();
                    DeadSound.Play();
                    return;
                }
                else if (Position.X - ballRadius > 1.0f * Aspect)
                {
                    Platforms[1].ReduceLife();
                    Pause();
                    this.ReInitialize();
                    DeadSound.Play();
                    return;
                }
            }
            Position += Direction * dt;
            particleSystem.Update(dt);
            particleSystem.Position = Position;
        }
        else
        {
            ResumeInSec -= dt;
            if (ResumeInSec < 0)
            {
                Paused = false;
            }
        }
    }

    public void SetScale(int Scale)
    {
        this.Scale = Scale;
    }

    public void Draw(Vector2 Offset)
    {
        if (!Paused)
        {
            particleSystem.Draw(spriteBatch, Scale, Offset);
        }
        else
        {
            string timeleft = ResumeInSec.ToString();
            if(timeleft.Length > 3)
            {
                timeleft = timeleft.Substring(0, 3);
            }
            spriteBatch.DrawString(PausedFont,
                "Kolejna szansa za " + timeleft + " sekund",
                new Vector2(0.5f * Aspect * Scale - PausedFont.MeasureString("Kolejna szansa za " + timeleft + " sekund").X / 2, 0.4f * Scale),
                Color.White);
        }
    }



    void ResetBallParticleSystem(float speed)
    {
        SetBallParticleSystem(speed);
        particleSystem.EmitterList[0].StartColor1 = Color.White;
        particleSystem.EmitterList[0].StartColor2 = Color.Black;
        particleSystem.EmitterList[0].EndColor1 = Color.Orange;
        particleSystem.EmitterList[0].EndColor2 = Color.Orange;
        particleSystem.EmitterList[1].StartColor1 = Color.White;
        particleSystem.EmitterList[1].StartColor2 = Color.Black;
        particleSystem.EmitterList[1].EndColor1 = Color.Orange;
        particleSystem.EmitterList[1].EndColor2 = Color.Orange;
    }

    void SetBallParticleSystem(float speed)
    {
        particleSystem.EmitterList[0].SecPerSpawn = new Vector2(0.001f / (speed * 2), 0.0015f / (speed * 2));
        particleSystem.EmitterList[0].Budget = (int)(1000 * 2 * speed);
        particleSystem.EmitterList[1].SecPerSpawn = new Vector2(0.001f / (speed * 2), 0.0015f / (speed * 2));
        particleSystem.EmitterList[1].Budget = (int)(1000 * 2 * speed);
        particleSystem.EmitterList[1].StartLife = new Vector2(0.375f / (speed / 1), 0.5f / (speed / 1));
        particleSystem.EmitterList[0].StartLife = new Vector2(0.375f / (speed / 1), 0.5f / (speed / 1));
        particleSystem.EmitterList[0].StartSpeed = new Vector2(0.00f, 0.18f * speed * 3);
    }
}